package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.*;
import cn.huiyunche.base.service.framework.redis.MindsJedisConnectionFactory;
import cn.huiyunche.base.service.framework.security.JwtAuthenicationFilter;
import cn.huiyunche.base.service.framework.utils.*;
import cn.huiyunche.base.service.interfaces.*;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.mappers.ext.DUserViewMapper;
import cn.huiyunche.base.service.mappers.ext.DWaybillViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.utils.DateUtils;
import cn.huiyunche.base.service.vo.*;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName: AuthServiceImpl
 * @Description: 用户授权接口实现类
 * @author: Aaron
 * @date: 2016年5月6日 下午2:10:04
 */
@Service
public class UserServiceImpl implements UserService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    private final String defaultPassword = "f56bac01407433e4ea792764724026==";

    @Autowired
    private SUserMapper sUserMapper = null;
    @Autowired
    private SUserDevicesMapper sUserDevicesMapper = null;
    @Autowired
    private MindsJedisConnectionFactory connectionFactory = null;
    @Autowired
    private JwtAuthenicationFilter jwtAuthenticationFilter = null;
    @Autowired
    private Md5PasswordEncoder passwordEncoder = null;
    @Autowired
    private SWaybillQuoteMapper waybillQuoteMapper = null;
    @Autowired
    private CDriverCertinfoMapper cDriverCertinfoMapper = null;
    @Autowired
    private SUserInviteMapper sUserInviteMapper = null;
    @Autowired
    private CTruckInfoMapper cTruckInfoMapper = null;
    @Autowired
    private BCompanyMapper bCompanyMapper = null;
    @Autowired
    private BScoresTurnoverService bScoresTurnoverService = null;
    // 用户积分余额
    @Autowired
    private BScoresService bScoresService = null;
    // 用户积分等级
    @Autowired
    private BScoresLevelService bScoresLevelService = null;

    @Autowired
    private TmsQueueService tmsQueueService = null;

    @Autowired
    private VersionService versionService = null;

    @Autowired
    private DWaybillViewMapper dWaybillViewMapper = null;

    @Autowired
    private DWaybillMapper dWaybillMapper = null;

    @Autowired
    private DUserMapper dUserMapper = null;

    @Autowired
    private DUserExtMapper dUserExtMapper = null;

    @Autowired
    private DUserPositionMapper dUserPositionMapper = null;

    @Autowired
    private DWaybillService dWaybillService = null;

    @Autowired
    private CodeService codeService = null;

    @Autowired
    private DUserViewMapper dUserViewMapper;

    @Autowired
    private DUserLicenseService dUserLicenseService;

    @Autowired
    private DWaybillLogisticsService dWaybillLogisticsService;

    @Autowired
    private SUserStatusMapper sUserStatusMapper;

    @Autowired
    private BCompanyUserMapper bCompanyUserMapper = null;

    @Autowired
    private SUserBindDeviceMapper sUserBindDeviceMapper = null;

    private SUserBindDeviceMapper getSUserBindDeviceMapper() {
        return this.sUserBindDeviceMapper;
    }

    private BCompanyUserMapper getBCompanyUserMapper() {
        return this.bCompanyUserMapper;
    }

    private DWaybillMapper getDWaybillMapper() {
        return this.dWaybillMapper;
    }

    private CodeService getCodeService() {
        return this.codeService;
    }

    private DWaybillService getDWaybillService() {
        return this.dWaybillService;
    }

    private DUserPositionMapper getDUserPositionMapper() {
        return this.dUserPositionMapper;
    }

    private DUserExtMapper getDUserExtMapper() {
        return this.dUserExtMapper;
    }

    private DUserMapper getDUserMapper() {
        return this.dUserMapper;
    }

    private DWaybillViewMapper getDWaybillViewMapper() {
        return this.dWaybillViewMapper;
    }

    private TmsQueueService getTmsQueueService() {
        return this.tmsQueueService;
    }

    public VersionService getVersionService() {
        return this.versionService;
    }

    private BScoresService getBScoresService() {
        return this.bScoresService;
    }

    private BScoresLevelService getBScoresLevelService() {
        return this.bScoresLevelService;
    }

    private BCompanyMapper getBCompanyMapper() {
        return this.bCompanyMapper;
    }

    private SUserInviteMapper getsUserInviteMapper() {
        return this.sUserInviteMapper;
    }

    private SWaybillQuoteMapper getWaybillQuoteMapper() {
        return waybillQuoteMapper;
    }

    private SUserDevicesMapper getSUserDevicesMapper() {
        return this.sUserDevicesMapper;
    }

    private MindsJedisConnectionFactory getConnectionFactory() {
        return this.connectionFactory;
    }

    private CDriverCertinfoMapper getcDriverCertinfoMapper() {
        return this.cDriverCertinfoMapper;
    }

    private CTruckInfoMapper getCTruckInfoMapper() {
        return this.cTruckInfoMapper;
    }

    private BScoresTurnoverService getBScoresTurnoverService() {
        return this.bScoresTurnoverService;
    }

    /**
     * @param phone    手机号
     * @param code     验证码
     * @param seconds  存储时长 单位:秒
     * @param userType 用户类型
     */
    public String setAuthCode(String phone, String code, int seconds, int userType) {
        LOGGER.info("UserServiceImpl.setAuthCode params : {}, {}, {}", phone, code, userType);
        Jedis jedis = this.getConnectionFactory().fetchJedisConnector();
        try {
            // String flag = jedis.setex(phone,seconds, code);
            String key = phone.concat(String.valueOf(userType));
            return jedis.setex(key, seconds, code).equalsIgnoreCase("ok") ? "发送成功！" : "发送失败！";
        } finally {
            jedis.close();
        }
    }

    /**
     * 根据手机号获取存储的验证码
     *
     * @param phone    手机号
     * @param userType 用户类型
     * @return
     */
    public String getAuthCode(String phone, int userType) {
        LOGGER.info("UserServiceImpl.getAuthCode param : {}, {}", phone, userType);
        Jedis jedis = this.getConnectionFactory().fetchJedisConnector();
        String code;
        try {
            String key = phone.concat(String.valueOf(userType));
            code = jedis.get(key);
            LOGGER.info("UserServiceImpl.getAuthCode return : {}", code);
        } finally {
            jedis.close();
        }
        return code;
    }

    @Override
    public boolean removeAuthcode(String key) {
        LOGGER.info("UserServiceImpl.removeAuthcode param : {}", key);
        Jedis jedis = this.getConnectionFactory().fetchJedisConnector();
        try {
            return jedis.del(key) > 0 ? true : false;
        } finally {
            jedis.close();
        }
    }

    @Override
    public Long add(String phone, String openid, String uuid, String deviceType, int userType, String password,
                    String invitedcode) {
        LOGGER.info("UserServiceImpl.add param : {}, {}, {}, {}, {}, {}, {}", phone, openid, uuid, deviceType, userType,
                password, invitedcode);
        SUser user = this.getByPhone(phone, Arrays.asList(userType));
        if (user == null) {
            user = new SUser();
            user.setPhone(phone);
            user.setEnable(EnabledEnum.T.getValue());// 默认启用
            user.setUserType(userType);
            if (UserTypeEnum.DRIVER.getValue() == userType) {
                if (StringUtils.isNotBlank(invitedcode)) {
                    user.setInvitedCode(invitedcode);
                    // 通过邀请码查询邀请码所属用户
                    SUserInviteExample example = new SUserInviteExample();
                    example.createCriteria().andInviteCodeEqualTo(invitedcode);
                    List<SUserInvite> sInvites = this.getsUserInviteMapper().selectByExample(example);
                    if (CollectionUtils.isNotEmpty(sInvites) && sInvites.size() > 0) {
                        SUserInvite sInvite = sInvites.get(0);// 得到用户ID
                        SUser u = this.selectByPrimaryKey(sInvite.getUserId());// 父推荐人
                        user.setCompanyCode(u.getCompanyCode());
                    }
                }
            }
            SUserDevices ud = new SUserDevices();
            user.setPwd(passwordEncoder.encodePassword(password, jwtAuthenticationFilter.getSecureKey()));
            if (StringUtils.isBlank(uuid)) {
                user.setOpenId(openid);
                this.getSUserMapper().insertSelective(user);
                ud.setUserId(user.getId());
                ud.setUuid(openid);
                ud.setDeviceType(deviceType);
                SUserDevicesExample search = new SUserDevicesExample();
                search.createCriteria().andDeviceTypeEqualTo(deviceType);
                ud.setLastDevice((long) (this.getSUserDevicesMapper().countByExample(search) + 1));
                this.getSUserDevicesMapper().insertSelective(ud);
            } else {
                this.getSUserMapper().insertSelective(user);
                ud.setUserId(user.getId());
                ud.setUuid(uuid);
                ud.setDeviceType(deviceType);
                SUserDevicesExample search = new SUserDevicesExample();
                search.createCriteria().andDeviceTypeEqualTo(deviceType);
                ud.setLastDevice((long) (this.getSUserDevicesMapper().countByExample(search) + 1));
                this.getSUserDevicesMapper().insertSelective(ud);
            }
            // 生成邀请码
            if (UserTypeEnum.DRIVER.getValue() == userType) {
                String serialCode = Md5PasswordEncoderUtils.getInvitationCode(user.getId() + "", 6);
                SUserInviteExample example = new SUserInviteExample();
                example.createCriteria().andInviteCodeEqualTo(serialCode);
                List<SUserInvite> sInvites = this.getsUserInviteMapper().selectByExample(example);
                if (CollectionUtils.isNotEmpty(sInvites) && sInvites.size() > 0) {
                    serialCode = Md5PasswordEncoderUtils.getInvitationCode(serialCode, 6);
                }
                SUserInvite invite = new SUserInvite();
                invite.setUserId(user.getId());
                invite.setInviteCode(serialCode);
                invite.setInviteCodePriod(6);
                try {
                    this.getsUserInviteMapper().insertSelective(invite);
                } catch (Exception e) {
                    LOGGER.error("insert invite error : {}", e);
                    throw new BusinessException("用户邀请数据异常");
                }
            } else if (UserTypeEnum.OWNER.getValue() == userType) {
                // 如果是托运个人注册 成功 则增加用户积分
                LOGGER.info("owner sing up add scores params userId : {}, userType : {}.", user.getId(), userType);
                this.getBScoresTurnoverService().addDiscountScores(user.getId(), userType);
            }
        } else {
            if (StringUtils.isBlank(uuid)) {
                user.setOpenId(StringUtils.isNotBlank(openid) == true ? openid : null);
                user.setUpdateTime(new Date());
                this.getSUserMapper().updateByPrimaryKeySelective(user);
                SUserDevices ud = new SUserDevices();
                ud.setUserId(user.getId());
                ud.setUuid(openid);
                ud.setDeviceType(deviceType);
                SUserDevicesExample search = new SUserDevicesExample();
                search.createCriteria().andDeviceTypeEqualTo(deviceType);
                ud.setLastDevice((long) (this.getSUserDevicesMapper().countByExample(search) + 1));
                this.getSUserDevicesMapper().insertSelective(ud);
            } else {
                SUserDevices ud = new SUserDevices();
                ud.setUserId(user.getId());
                ud.setUuid(uuid);
                ud.setDeviceType(deviceType);
                SUserDevicesExample search = new SUserDevicesExample();
                search.createCriteria().andDeviceTypeEqualTo(deviceType);
                ud.setLastDevice((long) (this.getSUserDevicesMapper().countByExample(search) + 1));
                this.getSUserDevicesMapper().insertSelective(ud);
            }
        }
        return user.getId();
    }

    public SUserMapper getSUserMapper() {
        return this.sUserMapper;
    }

    @Override
    public UserShowVo getCurrentUser() throws Exception {
        Long id = this.getCurrentUserVo().getId();
        SUser user = this.getSUserMapper().selectByPrimaryKey(id);
        if (user == null || !user.getEnable().equals(AvailableEnum.T.getValue())) {
            throw new BusinessException("用户不存在！");
        }
        String picKey = user.getPic();
        UserShowVo userShowVo = new UserShowVo();
        userShowVo.setPicKey(picKey);
        buildUserShowVo(user, userShowVo);
        return userShowVo;
    }

    @Override
    public SUser getById(long id) {
        return this.getSUserMapper().selectByPrimaryKey(id);
    }

    @Override
    public UserShowVo updateById(UserUpdateVo form) throws Exception {
        LOGGER.info("UserServiceImpl.updateById params : {}", form);
        SUser user = new SUser();
        user.setId(this.getCurrentUserVo().getId());
        user.setName(form.getName());
        user.setEmail(form.getEmail());
        user.setGender(form.getGender());
        user.setBirthday(form.getBirthday());
        user.setPic(form.getPic());
        user.setUpdateTime(new Date());
        user.setOpenId(form.getOpenid());
        user.setRealName(form.getRealname());
        if (form.getUserLevel() != null) {
            user.setUserLevel(form.getUserLevel().intValue());
        }
        if (form.getUserIntegral() != null) {
            user.setUserIntegral(form.getUserIntegral());
        }
        if (form.getUserIntegralSum() != null) {
            user.setUserIntegralSum(form.getUserIntegralSum());
        }
        if (StringUtils.isNotBlank(form.getCompanycode())) {
            user.setCompanyCode(Long.valueOf(form.getCompanycode()));
        }
        if (StringUtils.isNotBlank(form.getInvitedcode())) {
            user.setInvitedCode(form.getInvitedcode());
        }
        this.getSUserMapper().updateByPrimaryKeySelective(user);

        SUser cUser = this.getSUserMapper().selectByPrimaryKey(user.getId());
        UserShowVo userShowVo = new UserShowVo();
        userShowVo.setPicKey(cUser.getPic());
        buildUserShowVo(cUser, userShowVo);

        return userShowVo;
    }

    @Override
    public SUser getByConditions(String name, String pwd) {
        LOGGER.info("UserServiceImpl.getByConditions params : {}, {}", name, pwd);
        SUserExample uc = new SUserExample();
        SUserExample.Criteria userUcIntenal = uc.createCriteria();
        userUcIntenal.andNameEqualTo(name);
        uc.createCriteria().andPhoneEqualTo(name);
        uc.or(userUcIntenal);
        List<SUser> list = this.getSUserMapper().selectByExample(uc);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public SUser getByPhone(String phone, List<Integer> userTypes) {
        LOGGER.info("UserServiceImpl.getByPhone params : {}, {}", phone, userTypes);
        SUserExample search = new SUserExample();
        SUserExample.Criteria criteria = search.createCriteria();
        criteria.andPhoneEqualTo(phone);
        criteria.andUserTypeIn(userTypes).andEnableEqualTo(AvailableEnum.T.getValue());
        // if (UserTypeEnum.OWNER.getValue() == userType) {
        // SUserExample.Criteria criteria1 = search.createCriteria();
        // criteria1.andUserTypeEqualTo(UserTypeEnum.SCOMPANY.getValue());
        // search.or(criteria1);
        // }
        List<SUser> list = this.getSUserMapper().selectByExample(search);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public SUser getByPhone(String phone, List<Integer> userTypes, boolean isEnable) {
        LOGGER.info("UserServiceImpl.getByPhone params : {}, {}", phone, userTypes);
        SUserExample search = new SUserExample();
        SUserExample.Criteria criteria = search.createCriteria();
        criteria.andPhoneEqualTo(phone);
        if (isEnable) {
            criteria.andUserTypeIn(userTypes).andEnableEqualTo(AvailableEnum.T.getValue());
        } else {
            criteria.andUserTypeIn(userTypes);
        }
        // if (UserTypeEnum.OWNER.getValue() == userType) {
        // SUserExample.Criteria criteria1 = search.createCriteria();
        // criteria1.andUserTypeEqualTo(UserTypeEnum.SCOMPANY.getValue());
        // search.or(criteria1);
        // }
        List<SUser> list = this.getSUserMapper().selectByExample(search);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public SUser getByPhone(String phone, Integer userType) {
        LOGGER.info("UserServiceImpl.getByPhone params : {}, {}", phone, userType);
        SUserExample search = new SUserExample();
        SUserExample.Criteria criteria = search.createCriteria();
        criteria.andPhoneEqualTo(phone);
        criteria.andUserTypeEqualTo(userType).andEnableEqualTo(AvailableEnum.T.getValue());
        // if (UserTypeEnum.OWNER.getValue() == userType) {
        // SUserExample.Criteria criteria1 = search.createCriteria();
        // criteria1.andUserTypeEqualTo(UserTypeEnum.SCOMPANY.getValue());
        // search.or(criteria1);
        // }
        List<SUser> list = this.getSUserMapper().selectByExample(search);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public UserVo getCurrentUserVo() throws Exception {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            return (UserVo) authentication.getPrincipal();
        } catch (Exception e) {
            LOGGER.error("UserServiceImpl.getCurrentUserVo error : {}", e);
            e.printStackTrace();
            throw new BusinessException("获取当前用户信息异常！");
        }
    }

    @Override
    public SUser signIn(String phone, int userType, String password, String deviceType, String openid, String uuid)
            throws Exception {
        return addUserLoginDevice(phone, userType, password, deviceType, openid, uuid, null, null, false);
    }

    @Override
    public SUser webSignIn(String phone, int userType, String password, String deviceType, String openid, String uuid) throws Exception {
        return addUserLoginDevice(phone, userType, password, deviceType, openid, uuid, null, null, true);
    }

    private SUser getByPhoneOrName(String phone, List<Integer> userTypes) {
        LOGGER.info("UserServiceImpl.getByPhone params : {}, {}", phone, userTypes);
        SUserExample search = new SUserExample();
        SUserExample.Criteria criteria = search.createCriteria();
        criteria.andPhoneEqualTo(phone);
        criteria.andUserTypeIn(userTypes).andEnableEqualTo(AvailableEnum.T.getValue());
        List<SUser> phoneList = this.getSUserMapper().selectByExample(search);

        SUserExample search1 = new SUserExample();
        SUserExample.Criteria criteria1 = search1.createCriteria();
        criteria1.andNameEqualTo(phone);
        criteria1.andUserTypeIn(userTypes).andEnableEqualTo(AvailableEnum.T.getValue());
        List<SUser> nameList = this.getSUserMapper().selectByExample(search1);

        if (CollectionUtils.isNotEmpty(phoneList)) {
            return phoneList.get(0);
        } else if (CollectionUtils.isNotEmpty(nameList)) {
            return nameList.get(0);
        }
        return null;
    }

    @Override
    public SUser signIn(String phone, int userType, String password, String deviceType, String openid, String uuid,
                        String pushid, String clientType) throws Exception {
        return addUserLoginDevice(phone, userType, password, deviceType, openid, uuid, pushid, clientType, false);
    }

    @Override
    public int resetPwd(String phone, int userType, String password) throws Exception {
        LOGGER.info("UserServiceImpl.resetPwd params : {}", phone, userType, password);
        SUser user = this.getByPhone(phone, Arrays.asList(userType));
        if (user == null) {
            LOGGER.error("UserServiceImpl.resetPwd user is null");
            throw new BusinessException("用户未注册");
        }
        user.setPwd(passwordEncoder.encodePassword(password, jwtAuthenticationFilter.getSecureKey()));
        return this.getSUserMapper().updateByPrimaryKeySelective(user);
    }

    @Override
    public int cleanOpenId() throws Exception {
        UserVo vo = this.getCurrentUserVo();
        LOGGER.info("UserServiceImpl.cleanOpenId userId : {}", vo.getId());
        SUser user = new SUser();
        user.setId(vo.getId());
        user.setOpenId("");
        int res = 0;
        try {
            res = this.getSUserMapper().updateByPrimaryKeySelective(user);
        } catch (Exception e) {
            LOGGER.error("UserServiceImpl.cleanOpenId error : {}", e);
            throw new BusinessException("退出失败");
        }
        return res;
    }

    /**
     * 构建前端显示vo
     *
     * @param user
     * @return
     */
    public void buildUserShowVo(SUser user, UserShowVo vo) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        if (user != null) {

            if (user.getBirthday() != null) {
                vo.setBirthday(sdf.format(user.getBirthday()));
            }

            Long userId = user.getId();
            Integer userType = user.getUserType();
            LOGGER.info("select current user userId : {}, userType : {}.", userId, userType);
            vo.setCreateTime(user.getCreateTime());
            vo.setEmail(user.getEmail());
            vo.setEnable(user.getEnable());
            vo.setGender(user.getGender());
            vo.setId(userId);
            vo.setName(user.getName());
            vo.setOpenId(user.getOpenId());
            vo.setPhone(user.getPhone());
            vo.setUserStatus(user.getUserStatus());
            if (StringUtils.isNotBlank(user.getPic())) {
                vo.setPic(QiniuUtils.generateDownloadTicket("", user.getPic(), "2", "200", "200"));
            }
            vo.setRealName(user.getRealName());
            vo.setUpdateTime(user.getUpdateTime());
            vo.setUserType(userType);
            //vo.setCompanycode(user.getCompanyCode());
            vo.setInvitedcode(user.getInvitedCode() + "");
            if (UserTypeEnum.DRIVER.getValue() == userType) {
                CDriverCertinfoExample example = new CDriverCertinfoExample();
                example.createCriteria().andUserIdEqualTo(userId);
                List<CDriverCertinfo> certinfos = this.getcDriverCertinfoMapper().selectByExample(example);
                if (CollectionUtils.isNotEmpty(certinfos) && certinfos.size() > 0) {
                    vo.setDriverStatus(TruckAuditStatusEnum.getByValue(certinfos.get(0).getStatus()).getValue());
                } else {
                    vo.setDriverStatus(0);
                }
            }

            BCompanyUserExample example = new BCompanyUserExample();
            example.createCriteria().andUserIdEqualTo(userId);
            List<BCompanyUser> companyUsers = this.getBCompanyUserMapper().selectByExample(example);
            if (CollectionUtils.isNotEmpty(companyUsers)) {
                BCompanyUser companyUser = companyUsers.get(0);
                BCompany company = this.getBCompanyMapper().selectByPrimaryKey(companyUser.getCompanyId());
                vo.setCompanycode(company.getCompanyCode());
                vo.setCompanyName(company.getCompanyName());
            } else {
                vo.setCompanyName("");
            }

            LOGGER.info("select current user userId : {}, userType : {} add userlevel and userscores.", userId, userType);
            // 承运端 没有积分
            if (userType == UserTypeEnum.SCOMPANY.getValue()) {
                BScores userScores = this.getBScoresService().getUserScores(userId, userType);
                if (userScores != null) {
                    vo.setScores(userScores.getScores());
                    vo.setLevelName(userScores.getLevelName());
                } else {
                    BScoresLevel level = this.getBScoresLevelService().selectByLevel(userType, UserLevelEnum.LEVEL_A.getValue());
                    vo.setLevelName(level.getLevelName());
                    vo.setScores(BigDecimal.ZERO);
                }
            }
        }
    }

    @Override
    public int modifyUserStatus(int status) throws Exception {
        LOGGER.info("Start Class UserServiceImpl method modifyUserStatus start ....");
        if (StringUtils.isBlank(UserStatusEnum.getByValue(status).getText())) {
            LOGGER.info("status error : {}", status);
            throw new BusinessException("状态错误");
        }
        UserVo vo = this.getCurrentUserVo();
        SUser user = new SUser();
        user.setId(vo.getId());
        user.setUserStatus(UserStatusEnum.getByValue(status).getValue());
        int res = 0;
        try {
            res = this.getSUserMapper().updateByPrimaryKeySelective(user);
        } catch (Exception e) {
            LOGGER.error("updateByPrimaryKeySelective error : {}", e);
            if (UserStatusEnum.T.getValue() == status) {
                throw new BusinessException("上线失败");
            } else if (UserStatusEnum.F.getValue() == status) {
                throw new BusinessException("下线失败");
            }
        }
        if (res == 0) {
            if (UserStatusEnum.T.getValue() == status) {
                LOGGER.info("On-line failure");
                throw new BusinessException("上线失败");
            } else if (UserStatusEnum.F.getValue() == status) {
                LOGGER.info("Offline failure");
                throw new BusinessException("下线失败");
            }
        }
        LOGGER.info("End Class UserServiceImpl method modifyUserStatus start ....");
        return res;
    }

    @Override
    public UserShowVo bindWechat(UserUpdateVo form) throws Exception {
        LOGGER.info("UserServiceImpl.boundWeiXin params : {}", form);
        if (StringUtils.isBlank(form.getName())) {
            LOGGER.info("name is not null");
            throw new BusinessException("微信名称不能为空");
        } else if (StringUtils.isBlank(form.getOpenid())) {
            LOGGER.info("openid is not null");
            throw new BusinessException("OpenId不能为空");
        }
        SUser user = new SUser();
        user.setId(this.getCurrentUserVo().getId());
        user.setName(form.getName());
        user.setUpdateTime(new Date());
        user.setOpenId(form.getOpenid());
        if (StringUtils.isNotBlank(form.getCompanycode())) {
            user.setCompanyCode(Long.valueOf(form.getCompanycode()));
        }
        try {
            this.getSUserMapper().updateByPrimaryKeySelective(user);
        } catch (Exception e) {
            LOGGER.error("updateByPrimaryKeySelective error : {}", e);
        }

        SUser cUser = this.getSUserMapper().selectByPrimaryKey(user.getId());
        UserShowVo userShowVo = new UserShowVo();
        userShowVo.setPicKey(cUser.getPic());
        buildUserShowVo(cUser, userShowVo);

        return userShowVo;
    }

    @Override
    public Integer countByExample(SUserExample search) {
        return this.getSUserMapper().countByExample(search);
    }

    @Override
    public List<SUser> selectByExample(SUserExample search) {
        return this.getSUserMapper().selectByExample(search);
    }

    @Override
    public SUser selectByPrimaryKey(Long userId) {
        return this.getSUserMapper().selectByPrimaryKey(userId);
    }

    @Override
    public boolean isDriverEqualToCurrentUser(Long id) throws Exception {
        if (id == null || id == 0) {
            throw new IllegalArgumentException("订单id不能为空！");
        }
        SWaybillQuoteExample example = new SWaybillQuoteExample();
        example.createCriteria().andOrderIdEqualTo(id).andStatusEqualTo(WayBillQuoteStatusEnum.SELECTED.getValue())
                .andUserIdEqualTo(this.getCurrentUserVo().getId());
        List<SWaybillQuote> quote = this.getWaybillQuoteMapper().selectByExample(example);
        return CollectionUtils.isNotEmpty(quote);
    }

    @Override
    public Result<Map<String, Object>> isCertifithrough(String phone) {
        Result<Map<String, Object>> result = new Result<Map<String, Object>>(false, "该用户未认证通过.");

        SUserExample userEexample = new SUserExample();
        userEexample.createCriteria().andUserTypeEqualTo(UserTypeEnum.DRIVER.getValue()).andPhoneEqualTo(phone);
        List<SUser> userList = this.sUserMapper.selectByExample(userEexample);
        if (userList.size() == 1) {
            SUser sUser = userList.get(0);
            Long userId = sUser.getId();

            // 查询司机身份认证表 c_driver_certinfos
            CDriverCertinfoExample driverExample = new CDriverCertinfoExample();
            driverExample.createCriteria().andUserIdEqualTo(userId);
            List<CDriverCertinfo> driverList = this.getcDriverCertinfoMapper().selectByExample(driverExample);
            if (driverList.size() == 1) {
                int driverStatus = driverList.get(0).getStatus();
                if (driverStatus == TruckAuditStatusEnum.AUDIT_PASS.getValue()) {
                    // 司机车辆认证 c_truck_info
                    CTruckInfoExample truckExample = new CTruckInfoExample();
                    truckExample.createCriteria().andUserIdEqualTo(userId);
                    List<CTruckInfo> truckList = this.getCTruckInfoMapper().selectByExample(truckExample);
                    if (truckList.size() == 1) {
                        Integer truckStatus = truckList.get(0).getStatus();
                        if (truckStatus == TruckAuditStatusEnum.AUDIT_PASS.getValue()) {
                            Map<String, Object> map = new HashMap<String, Object>();
                            map.put("userId", userId);
                            map.put("userName", sUser.getRealName());
                            result.setData(map);
                            result.setSuccess(true);
                            result.setMessage("该司机认证通过.");
                        }
                    }

                }
            }

        }
        return result;
    }

    @Override
    public Result<String> checkUser() throws Exception {
        Result<String> r = new Result<>(true);
        UserVo uv = this.getCurrentUserVo();
        if (null == uv) {
            r.setSuccess(false);
            r.setMessage("获取用户信息失败");
            return r;
        }
        SUser su = this.getById(uv.getId());
        if (null == su) {
            r.setSuccess(false);
            r.setMessage("获取用户信息失败");
            return r;
        }
        if (su.getUserType() != uv.getType()) {
            r.setSuccess(false);
            r.setMessage("获取用户信息失败");
            return r;
        }
        return r;
    }

    private SUser addUserLoginDevice(String phone, int userType, String password, String deviceType, String openid,
                                     String uuid, String pushid, String clientType, boolean isPcLogin) throws Exception {
        LOGGER.info("UserServiceImpl.signIn parama : {}, {}, {}, {}, {}, {}, {}, {}", phone, userType, password, deviceType,
                openid, uuid, pushid, clientType);
        SUser user = null;
        if (isPcLogin) {
            user = this.getByPhoneOrName(phone, Arrays.asList(userType));
        } else {
            user = this.getByPhone(phone, Arrays.asList(userType));
        }
        if (user == null) {
            throw new BusinessException("用户未注册");
        }
        if (!passwordEncoder.isPasswordValid(user.getPwd(), password, jwtAuthenticationFilter.getSecureKey())) {
            throw new BusinessException("用户名或密码错误");
        }
        if (StringUtils.isBlank(uuid)) {
            user.setOpenId(StringUtils.isNotBlank(openid) == true ? openid : null);
            user.setUpdateTime(new Date());
            this.getSUserMapper().updateByPrimaryKeySelective(user);
            SUserDevices ud = new SUserDevices();
            ud.setUserId(user.getId());
            ud.setUuid(openid);
            ud.setDeviceType(deviceType);
            SUserDevicesExample search = new SUserDevicesExample();
            search.createCriteria().andDeviceTypeEqualTo(deviceType);
            ud.setLastDevice((long) (this.getSUserDevicesMapper().countByExample(search) + 1));
            this.getSUserDevicesMapper().insertSelective(ud);
        } else {
            SUserDevices ud = new SUserDevices();
            ud.setUserId(user.getId());
            ud.setUuid(uuid);
            ud.setPushid(pushid);
            ud.setDeviceType(deviceType);
            SUserDevicesExample search = new SUserDevicesExample();
            search.createCriteria().andDeviceTypeEqualTo(deviceType);
            ud.setLastDevice((long) (this.getSUserDevicesMapper().countByExample(search) + 1));
            this.getSUserDevicesMapper().insertSelective(ud);
            //this.insertDUserBindDevice(user.getId(), clientType, deviceType, uuid);
        }
        return user;
    }

    /**
     * 插入司机账号设备绑定
     *
     * @throws BusinessException
     */
    private void insertDUserBindDevice(Long userId, String clientType, String deviceType, String uuId) throws Exception {
        LOGGER.info("insertDUserBindDevice params userId:{}, clientType: {}, deviceType: {}, uuId: {}", userId, clientType, deviceType, uuId);
        SUserBindDeviceExample example = new SUserBindDeviceExample();
        example.createCriteria().andUserIdEqualTo(userId).andBindStatusEqualTo(SUserBindStatusEnum.T.getValue());
        List<SUserBindDevice> userBindDevices = this.getSUserBindDeviceMapper().selectByExample(example);
        LOGGER.info("selectSUserBindeDevice result record size: {}", userBindDevices.size());
        if (CollectionUtils.isEmpty(userBindDevices)) {
            SUserBindDevice device = new SUserBindDevice();
            device.setBindStatus(SUserBindStatusEnum.T.getValue());
            device.setClientType(clientType);
            device.setDeviceType(deviceType);
            device.setUuid(uuId);
            device.setUserId(userId);
            device.setUpdateTime(new Date());
            this.getSUserBindDeviceMapper().insertSelective(device);
        } else {
            SUserBindDevice device = userBindDevices.get(0);
            LOGGER.info("result device: {}", device.toString());
            if (!device.getUuid().equals(uuId)) {
                throw new BusinessException("此账号与前机主没有解除手机绑定关系，请拨打：400-818-7999 联系客服协助处理");
            }
        }
    }

    @Override
    public Result<Object> checkDrawUser() throws Exception {
        Result<Object> r = new Result<>(false);
        UserVo uv = this.getCurrentUserVo();
        if (null == uv) {
            r.setMessage("用户信息不存在");
            return r;
        }
        // 设置缓存
        String drawUserId = HYCUtils.encryptBankCard(uv.getId() + "");
        HYCUtils.setDrawUserCodeCache(drawUserId);
        r.setData(drawUserId);
        r.setSuccess(true);
        return r;
    }

    @Override
    public UserShowVo upgrades(String code) throws Exception {
        LOGGER.info("Fill in the company authentication code for the current user : {}", code);
        if (StringUtils.isBlank(code)) {
            LOGGER.info("company code is not null");
            throw new BusinessException("企业码不能为空");
        }
        // 获取当前用户
        UserVo user = this.getCurrentUserVo();
        // 根据code、公司类型查询公司信息
        BCompanyExample example = new BCompanyExample();
        example.createCriteria().andSecuritycodeEqualTo(code).andCompanyCategoryEqualTo(CompanyTypeEnum.SCOMPANY.getValue());
        List<BCompany> companyList = this.getBCompanyMapper().selectByExample(example);
        if (CollectionUtils.isNotEmpty(companyList) && companyList.size() > 0) {
            BCompany company = companyList.get(0);
            // 管理员账号ID只回写一次
            if (company.getAdminId() == null || company.getAdminId() == 0) {
                company.setAdminId(user.getId());
                this.getBCompanyMapper().updateByPrimaryKeySelective(company);
            }
            // 更新用户所属公司编码、用户类型信息
            SUser us = new SUser();
            us.setId(user.getId());
            us.setCompanyCode(company.getCompanyCode());
            us.setUserType(UserTypeEnum.SCOMPANY.getValue());
            this.getSUserMapper().updateByPrimaryKeySelective(us);
        } else {
            LOGGER.info("The current company authentication code does not exist");
            throw new BusinessException("输入的企业码错误");
        }
        SUser cUser = this.getSUserMapper().selectByPrimaryKey(user.getId());
        UserShowVo userShowVo = new UserShowVo();
        userShowVo.setPicKey(cUser.getPic());
        buildUserShowVo(cUser, userShowVo);
        return userShowVo;
    }

    /**
     * 更新用户
     *
     * @param user
     * @return
     */
    @Override
    public int updateByRecord(SUser user) {
        LOGGER.info("update user params user : {}.", JSON.toJSONString(user));
        try {
            return this.getSUserMapper().updateByPrimaryKeySelective(user);
        } catch (Exception e) {
            LOGGER.info("update user params user : {}, error.", JSON.toJSONString(user), e);
            throw new BusinessException("更新用户信息异常");
        }
    }

    @Override
    public Map<String, Object> refresh() throws Exception {
        UserShowVo userVo = this.getCurrentUser();
        Map<String, Object> map = new HashMap<>();
        if (userVo == null) {
            LOGGER.info("current user is null");
            throw new BusinessException("获取当前用户信息异常");
        }
        // 添加司机排队
        // this.getTmsQueueService().appendDriver(userVo.getPhone());
        // 获取排队中的数据
        TmsQueueDriverRtnVo tmsDV = this.getTmsQueueService().getMyself(userVo.getPhone());
        // 查询运单信息
        List<Integer> statusList = new ArrayList<>();
        statusList.add(DWaybillStatusEnum.DEPARTURE.getValue());
        statusList.add(DWaybillStatusEnum.INTRANSIT.getValue());
        statusList.add(DWaybillStatusEnum.DEAL_CAR.getValue());
        ShowOrderVo sov = this.getDWaybillViewMapper().selectOrderInfo(userVo.getId(), statusList);
//        ShowOrderVo sov = null;
        if (sov != null) {
            if (sov.getOrderTime() != null) {
                String dt = DateUtils.getStringFromDate(sov.getOrderTime(), "yyyy-MM-dd");
                String current = DateUtils.getStringFromDate(new Date(), "yyyy-MM-dd");
                String time = DateUtils.getStringFromDate(sov.getOrderTime(), "yyyy-MM-dd HH:mm");
                if (dt.equals(current)) {
                    sov.setShowWaybillDate("今日运单");
                    sov.setShowDate("今天 " + time.substring(11, 16));
                    sov.setShowTime(time.substring(11, 16));
                } else {
                    sov.setShowWaybillDate(dt);
                    sov.setShowDate(dt + " " + time.substring(11, 16));
                    sov.setShowTime(time.substring(11, 16));
                }
            }
        }
        ShowQueueVo sqv = new ShowQueueVo();
        if (tmsDV != null) {
            sqv.setFrontNumber(tmsDV.getIndex());
            sqv.setOrderNumber(tmsDV.getOrderNumber());
            sqv.setRankNumber(tmsDV.getNubmer());
        }
        map.put("queue", sqv);
        map.put("order", sov);
        return map;
    }

    @Override
    public Map<String, Object> online() throws Exception {
        UserShowVo userVo = this.getCurrentUser();
        Map<String, Object> map = new HashMap<>();
        if (userVo == null) {
            LOGGER.info("current user is null");
            throw new BusinessException("获取当前用户信息异常");
        }
        if (userVo.getUserType() != UserTypeEnum.SEND_DRIVER.getValue()) {
            LOGGER.info("司机不属于人送司机");
            throw new BusinessException("您不属于人送司机，不可上线排队");
        }

        SUser user = this.getSUserMapper().selectByPrimaryKey(userVo.getId());
        if (user == null || !user.getEnable().equals(AvailableEnum.T.getValue())) {
            throw new BusinessException("用户不存在！");
        }


        SUserStatus sUserStatus = new SUserStatus();
        sUserStatus.setUserId(user.getId());
        sUserStatus.setUserStatus(UserStatusEnum.T.getValue());
        int res = 0;
        try {

            SUserStatusExample example = new SUserStatusExample();
            example.createCriteria().andUserIdEqualTo(user.getId());
            example.setOrderByClause("gmt_create desc");
            List<SUserStatus> list = sUserStatusMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(list)) {
                if (UserStatusEnum.F.getValue() == list.get(0).getUserStatus()) {
                    // 更新用户状态
                    res = sUserStatusMapper.insertSelective(sUserStatus);
                }
            } else {
                // 更新用户状态
                res = sUserStatusMapper.insertSelective(sUserStatus);
            }
        } catch (Exception e) {
            LOGGER.error("UserStatusMapper.insertSelective error : {}", e);
            throw new BusinessException("上线失败");
        }
        if (res > 0) {
            // 添加司机排队
            ShowOrderVo orderVo = this.getDWaybillService().getIntransitListByPage();
            if (orderVo == null) {
                this.getTmsQueueService().appendDriver(userVo.getPhone());
                LOGGER.info("UserServiceImpl.onLine info user:{}，onLine_time:{}.", user.getPhone(),
                        new DateTime().toString(DateUtils.FORMAT_DATETIME));
            }
            // 获取排队中的数据
            TmsQueueDriverRtnVo tmsDV = this.getTmsQueueService().getMyself(userVo.getPhone());
            // 查询运单信息
            List<Integer> statusList = new ArrayList<>();
            statusList.add(DWaybillStatusEnum.DEPARTURE.getValue());
            statusList.add(DWaybillStatusEnum.INTRANSIT.getValue());
            statusList.add(DWaybillStatusEnum.DEAL_CAR.getValue());
            ShowOrderVo sov = this.getDWaybillViewMapper().selectOrderInfo(userVo.getId(), statusList);
            if (sov != null) {
                if (sov.getOrderTime() != null) {
                    String dt = DateUtils.getStringFromDate(sov.getOrderTime(), "yyyy-MM-dd");
                    String current = DateUtils.getStringFromDate(new Date(), "yyyy-MM-dd");
                    String time = DateUtils.getStringFromDate(sov.getOrderTime(), "yyyy-MM-dd HH:mm");
                    if (dt.equals(current)) {
                        sov.setShowWaybillDate("今日运单");
                        sov.setShowDate("今天 " + time.substring(11, 16));
                        sov.setShowTime(time.substring(11, 16));
                    } else {
                        sov.setShowWaybillDate(dt);
                        sov.setShowDate(dt + " " + time.substring(11, 16));
                        sov.setShowTime(time.substring(11, 16));
                    }
                }
            }
            ShowQueueVo sqv = new ShowQueueVo();
            if (tmsDV != null) {
                sqv.setFrontNumber(tmsDV.getIndex());
                sqv.setOrderNumber(tmsDV.getOrderNumber());
                sqv.setRankNumber(tmsDV.getNubmer());
            }
            map.put("queue", sqv);
            map.put("order", sov);
        }
        return map;
    }

    @Override
    public int offline() throws Exception {
        UserVo userVo = this.getCurrentUserVo();
        if (userVo == null) {
            LOGGER.info("current user is null");
            throw new BusinessException("获取当前用户信息异常");
        }

        SUser user = this.getSUserMapper().selectByPrimaryKey(userVo.getId());
        if (user == null || !user.getEnable().equals(AvailableEnum.T.getValue())) {
            throw new BusinessException("用户不存在！");
        }
        SUserStatus sUserStatus = new SUserStatus();
        sUserStatus.setUserId(user.getId());
        sUserStatus.setUserStatus(UserStatusEnum.F.getValue());
        int res = 0;
        try {

            SUserStatusExample example = new SUserStatusExample();
            example.createCriteria().andUserIdEqualTo(user.getId());
            example.setOrderByClause("gmt_create desc");
            List<SUserStatus> list = sUserStatusMapper.selectByExample(example);
            if (CollectionUtils.isNotEmpty(list)) {
                if (UserStatusEnum.T.getValue() == list.get(0).getUserStatus()) {
                    // 更新用户状态
                    res = sUserStatusMapper.insertSelective(sUserStatus);
                }
            } else {
                // 更新用户状态
                res = sUserStatusMapper.insertSelective(sUserStatus);
            }
        } catch (Exception e) {
            LOGGER.error("sUserStatusMapper.insertSelective error : {}", e);
            throw new BusinessException("下线失败");
        }
        if (res > 0) {
            this.getTmsQueueService().removeDriver(userVo.getUsername());
            LOGGER.info("UserServiceImpl.offLine info user:{}，offLine_time:{}.", user.getPhone(),
                    new DateTime().toString(DateUtils.FORMAT_DATETIME));
        }
        return res;
    }

    @Override
    public Boolean isTmsUser(String phone) throws Exception {
        String loginName = phone;
        int userType = UserTypeEnum.SEND_DRIVER.getValue();
        int userTypeConsumer = UserTypeEnum.CONSUMER_DRIVER.getValue();
        if (StringUtils.isBlank(loginName)) {
            UserShowVo usv = getCurrentUser();
            if (usv.getUserType() != userType || usv.getUserType() != userTypeConsumer) {
                return false;
            }
            loginName = usv.getPhone();
        } else {
            if (null == getByPhone(phone, Arrays.asList(userType)) && null == getByPhone(phone, Arrays.asList(userTypeConsumer))) {
                return false;
            }
        }
        DUserExample due = new DUserExample();
        due.createCriteria().andLoginNameEqualTo(loginName).andEnableEqualTo(true).andTypeEqualTo(TmsUserTypeEnum.DRIVER.getValue());
        return this.dUserMapper.selectByExample(due).size() > 0;
    }

    @Override
    public UserShowVo getCurrentUserInfo() throws Exception {
        UserShowVo userVo = this.getCurrentUser();
        if (null == userVo || !userVo.getEnable().equals(AvailableEnum.T.getValue())) {
            return null;
        }
        String phone = userVo.getPhone();
        LOGGER.info("current user type: {}, phone: {}", userVo.getUserType(), phone);
        if (userVo.getUserType() != UserTypeEnum.CONSUMER_DRIVER.getValue()) {
            return this.getCurrentUser();
        }
        // 判断当前用户是中联导入用户还是APP注册用户
        DUserExample example = new DUserExample();
        example.createCriteria().andLoginNameEqualTo(phone).andEnableEqualTo(true).andTypeEqualTo(TmsUserTypeEnum.DRIVER.getValue());
        List<DUser> dUsers = this.getDUserMapper().selectByExample(example);
        UserShowVo showVo = new UserShowVo();
        if (CollectionUtils.isNotEmpty(dUsers)) {
            DUser user = dUsers.get(0);
            // 查询用户扩展信息
            DUserExtExample extExample = new DUserExtExample();
            extExample.createCriteria().andUserIdEqualTo(user.getId());
            List<DUserExt> dExts = this.getDUserExtMapper().selectByExample(extExample);
            showVo.setPhone(phone);
            if (CollectionUtils.isNotEmpty(dExts)) {
                DUserExt due = dExts.get(0);
                Date birthday = due.getBirthday();
                if (null != birthday) {
                    showVo.setBirthday(DateUtils.getStringFromDate(birthday, "yyyy-MM-dd"));
                }
                String gender = due.getGender();
                if (StringUtils.isBlank(gender)) {
                    gender = GenderEnum.T.getValue();
                }
                showVo.setGender(GenderEnum.getByValue(String.valueOf(gender)).getValue());
                showVo.setDriverStatus(TruckAuditStatusEnum.AUDIT_PASS.getValue());
                showVo.setId(userVo.getId());
            }
            return showVo;
        } else {
            return this.getCurrentUser();
        }
    }

    @Override
    public UserShowVo updateUserInfo(UserUpdateVo form) throws Exception {
        UserVo userVo = this.getCurrentUserVo();
        SUser user = new SUser();
        user.setId(userVo.getId());
        user.setName(form.getName());
        user.setEmail(form.getEmail());
        user.setGender(form.getGender());
        user.setBirthday(form.getBirthday());
        user.setPic(form.getPic());
        user.setUpdateTime(new Date());
        user.setOpenId(form.getOpenid());
        user.setRealName(form.getRealname());
        user.setPic(form.getPic());
        if (form.getUserLevel() != null) {
            user.setUserLevel(form.getUserLevel().intValue());
        }
        if (form.getUserIntegral() != null) {
            user.setUserIntegral(form.getUserIntegral());
        }
        if (form.getUserIntegralSum() != null) {
            user.setUserIntegralSum(form.getUserIntegralSum());
        }
        if (StringUtils.isNotBlank(form.getCompanycode())) {
            user.setCompanyCode(Long.valueOf(form.getCompanycode()));
        }
        if (StringUtils.isNotBlank(form.getInvitedcode())) {
            user.setInvitedCode(form.getInvitedcode());
        }
        this.getSUserMapper().updateByPrimaryKeySelective(user);

        // 判断当前用户是中联导入用户还是APP注册用户
        DUserExample example = new DUserExample();
        example.createCriteria().andLoginNameEqualTo(userVo.getUsername()).andEnableEqualTo(true).andTypeEqualTo(TmsUserTypeEnum.DRIVER.getValue());
        List<DUser> dUsers = this.getDUserMapper().selectByExample(example);
        UserShowVo showVo = new UserShowVo();
        if (CollectionUtils.isNotEmpty(dUsers)) {
            DUser dUser = dUsers.get(0);
            // 查询用户扩展信息
            DUserExtExample extExample = new DUserExtExample();
            extExample.createCriteria().andUserIdEqualTo(dUser.getId());
            List<DUserExt> dExts = this.getDUserExtMapper().selectByExample(extExample);
            showVo.setPhone(userVo.getUsername());
            if (CollectionUtils.isNotEmpty(dExts)) {
                DUserExt due = dExts.get(0);
                due.setBirthday(form.getBirthday());
                due.setGender(form.getGender());
                // 更新人送车用户扩展信息
                this.getDUserExtMapper().updateByPrimaryKeySelective(due);

                DUserExt duext = this.getDUserExtMapper().selectByPrimaryKey(due.getId());
                Date birthday = duext.getBirthday();
                if (null != birthday) {
                    showVo.setBirthday(DateUtils.getStringFromDate(birthday, "yyyy-MM-dd"));
                }
                String gender = duext.getGender();
                if (StringUtils.isBlank(gender)) {
                    gender = GenderEnum.T.getValue();
                }
                showVo.setGender(GenderEnum.getByValue(String.valueOf(gender)).getValue());
                showVo.setDriverStatus(TruckAuditStatusEnum.AUDIT_PASS.getValue());
                showVo.setId(userVo.getId());
            } else {
                SUser cUser = this.getSUserMapper().selectByPrimaryKey(user.getId());
                buildUserShowVo(cUser, showVo);
            }
            if (StringUtils.isNotBlank(form.getPic())) {
                showVo.setPic(QiniuUtils.generateDownloadTicket("", form.getPic(), "2", "200", "200"));
                showVo.setPicKey(form.getPic());
            }
            return showVo;
        } else {
            SUser cUser = this.getSUserMapper().selectByPrimaryKey(user.getId());
            showVo.setPicKey(cUser.getPic());
            buildUserShowVo(cUser, showVo);
            return showVo;
        }
    }

    @Override
    public Long addUserPosition(UserPositionVo upv) throws Exception {
        UserShowVo usv = this.getCurrentUser();
        LOGGER.info("addUserPosition params: {}, current user: {}", upv, usv);
        DUserPosition dup = new DUserPosition();
        try {
            PropertyUtils.copyProperties(dup, upv);
        } catch (Exception e) {
            LOGGER.error("copy DUserPositionVo error: {}", e);
            e.printStackTrace();
        }
        dup.setUserId(usv.getId());

        //如果有执行中运单，位置信息有变动则存
        handleDWaybillLogistics(usv.getId(), upv);

        //获取最后一次上报的位置信息
        DUserPositionExample example = new DUserPositionExample();
        example.setOrderByClause(" create_time desc ");
        example.createCriteria().andUserIdEqualTo(usv.getId())
                .andCreateTimeGreaterThanOrEqualTo(new DateTime().withMillisOfDay(0).toDate())
                .andCreateTimeLessThan(new DateTime().withMillisOfDay(0).plusDays(1).toDate());
        List<DUserPosition> dups = this.getDUserPositionMapper().selectByExample(example);
        String start = "";
        if (CollectionUtils.isNotEmpty(dups)) {
            DUserPosition position = dups.get(0);
            start = position.getLatitude() + "," + position.getLongitude();
        }
        String end = dup.getLatitude() + "," + dup.getLongitude();
        if (start == "") {
            this.getDUserPositionMapper().insertSelective(dup);
            // 判断司机是否在送车
//			waybillLogistics(usv, upv);
        }
        if (start != "") {
            String json = BaiDuMapUtils.distance(start, end, "JSON");
            Gson gson = new Gson();
            if (StringUtils.isNotBlank(json)) {
                BaiDuDistance dis = gson.fromJson("{" + json + "}", BaiDuDistance.class);
                if (dis != null) {
                    BigDecimal distance = BigDecimal.valueOf(dis.getDistance().getValue()).divide(BigDecimal.valueOf(1000));
                    List<BCode> bCodes = this.getCodeService().getBCodeByClassCode("OFFSET_VALUE");
                    if (CollectionUtils.isNotEmpty(bCodes)) {
                        BCode bCode = bCodes.get(0);
                        int rs = distance.compareTo(BigDecimal.valueOf(Long.valueOf(bCode.getCode())));
                        if (rs == 1) {
                            this.getDUserPositionMapper().insertSelective(dup);
                            // 判断司机是否在送车
//							waybillLogistics(usv, upv);
                        }
                    }

                }
            }
        }
        return dup.getId();
    }

    /**
     * 新增运单在途信息
     *
     * @param userId
     * @param upv
     * @return
     * @throws Exception
     */
    private void handleDWaybillLogistics(Long userId, UserPositionVo upv) throws Exception {

        //查询当前用户所以在途运单信息
        DWaybillExample example = new DWaybillExample();
        example.createCriteria().andUserIdEqualTo(userId).andWaybillStatusEqualTo(DWaybillStatusEnum.INTRANSIT.getValue());
        example.setOrderByClause(" create_time DESC ");
        List<DWaybill> waybills = this.getDWaybillMapper().selectByExample(example);

        //
        waybills.forEach(dWaybill -> {

            List<DWaybillLogistics> list = dWaybillLogisticsService.getListByDWaybillId(dWaybill.getId());

            if (CollectionUtils.isEmpty(list)) {
                DWaybillLogistics logistics = new DWaybillLogistics();
                BeanUtils.copyProperties(upv, logistics);
                logistics.setWaybillId(dWaybill.getId());

                dWaybillLogisticsService.add(logistics);
            } else {
                DWaybillLogistics logistics = list.get(0);

                String start = logistics.getLatitude() + "," + logistics.getLongitude();
                String end = upv.getLatitude() + "," + upv.getLongitude();

                String json = BaiDuMapUtils.distance(start, end, "JSON");
                Gson gson = new Gson();
                if (StringUtils.isNotBlank(json)) {
                    BaiDuDistance dis = gson.fromJson("{" + json + "}", BaiDuDistance.class);
                    if (dis != null) {
                        BigDecimal distance = BigDecimal.valueOf(dis.getDistance().getValue()).divide(BigDecimal.valueOf(1000));
                        List<BCode> bCodes = this.getCodeService().getBCodeByClassCode("OFFSET_VALUE");
                        if (CollectionUtils.isNotEmpty(bCodes)) {
                            BCode bCode = bCodes.get(0);
                            int rs = distance.compareTo(BigDecimal.valueOf(Long.valueOf(bCode.getCode())));
                            if (rs == 1) {
                                logistics = new DWaybillLogistics();
                                BeanUtils.copyProperties(upv, logistics);
                                logistics.setWaybillId(dWaybill.getId());
                                dWaybillLogisticsService.add(logistics);
                            }
                        }

                    }
                }
            }
            OrderDriverLocationInfo odli = new OrderDriverLocationInfo();
            BeanUtils.copyProperties(upv, odli);
            odli.setOrderilineid(dWaybill.getOrderLineId());
            odli.setReporttime(new Date());

            SUser sUser = this.selectByPrimaryKey(userId);
            DUserExample dUserExample = new DUserExample();
            dUserExample.createCriteria().andLoginNameEqualTo(sUser.getPhone()).andEnableEqualTo(true).andTypeEqualTo(TmsUserTypeEnum.DRIVER.getValue());
            List<DUser> dUsers = this.getDUserMapper().selectByExample(dUserExample);
            if (CollectionUtils.isNotEmpty(dUsers)) {
                DUserExtExample extExample = new DUserExtExample();
                extExample.createCriteria().andUserIdEqualTo(dUsers.get(0).getId());
                List<DUserExt> dExts = this.getDUserExtMapper().selectByExample(extExample);
                if (CollectionUtils.isNotEmpty(dExts)) {
                    odli.setVccard(dExts.get(0).getIdNo());
                }
            }
            odli.setVcname(sUser.getRealName());
            odli.setVcorderno(dWaybill.getOrderCode());
            try {
                this.getDWaybillService().pushOrderDriverLocation(odli);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public Result<String> openAccount(String phone) {
        Result<String> result = new Result<>(true, "开通成功");
        if (StringUtils.isEmpty(phone) || phone.length() != 11) {
            result.setSuccess(false);
            result.setMessage("输入手机号不能为空或格式不正确");
            return result;
        }
        SUser sUser = this.getUserByPhone(phone);
        if (null == sUser) {
            result.setSuccess(false);
            result.setMessage("系统中未查询到此司机账号:" + phone);
            return result;
        }
        //String newPwd = sUser.getPwd().replaceAll("==", "00");
        //sUser.setPwd(newPwd);
        sUser.setEnable(AvailableEnum.T.getValue());
        this.getSUserMapper().updateByPrimaryKeySelective(sUser);
        return result;
    }

    @Override
    public Result<String> disableAccount(String phone) {
        Result<String> result = new Result<>(true, "禁用成功");
        if (StringUtils.isEmpty(phone) || phone.length() != 11) {
            result.setSuccess(false);
            result.setMessage("输入手机号不能为空或格式不正确");
            return result;
        }
        SUser user = this.getUserByPhone(phone);
        if (null == user) {
            result.setSuccess(false);
            result.setMessage("系统中未查询到此司机账号:" + phone);
            return result;
        }
        //user.setPwd(defaultPassword);
        user.setEnable(AvailableEnum.F.getValue());
        this.getSUserMapper().updateByPrimaryKeySelective(user);
        return result;
    }

    @Override
    public SUser getUserByPhone(String phone) {
        SUserExample example = new SUserExample();
        example.createCriteria().andPhoneEqualTo(phone).andUserTypeEqualTo(UserTypeEnum.SEND_DRIVER.getValue());
        List<SUser> users = this.getSUserMapper().selectByExample(example);
        if (CollectionUtils.isEmpty(users)) {
            return null;
        }
        return users.get(0);
    }

    @Override
    public List<SUser> getByIds(List<Long> subUserIds) {
        LOGGER.info("getByIds params : {}", subUserIds.size());
        if (CollectionUtils.isEmpty(subUserIds)) {
            LOGGER.error("getByIds params subUserIds must not empty");
            throw new IllegalArgumentException("用户主键不能为空");
        }

        SUserExample example = new SUserExample();
        example.createCriteria().andIdIn(subUserIds);

        return this.selectByExample(example);
    }

    @Override
    public Map<String, Object> getDriversBySUserIdForSupplier(PageVo page, List<Long> userIds) {
        LOGGER.info("getDriversBySUserIdForSupplier params : {}, {}", page, userIds.size());

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("userIds", userIds);

        //可用
        paramsMap.put("enable", true);

        //分供方司机用户类型
        paramsMap.put("userType", UserTypeEnum.CONSUMER_DRIVER.getValue());

        if (null != page) {
            String orderByClause = StringUtils.isNotBlank(page.getOrder()) == true ? page.getOrder()
                    : " su.id";
            paramsMap.put("limitStart", page.getStartIndex());
            paramsMap.put("limitEnd", page.getPageSize());
            paramsMap.put("orderByClause", orderByClause);
            paramsMap.put("page", page);

            page.setTotalRecord(dUserViewMapper.countDriversBySUserIdForSupplier(paramsMap));
        }

        List<SupplierDriverVo> list = dUserViewMapper.getDriversBySUserIdForSupplier(paramsMap);
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> dUserIds = list.stream().mapToLong(vo -> vo.getDid()).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
            List<DUserLicense> licenses = dUserLicenseService.getListByUserIds(dUserIds);
            if (CollectionUtils.isNotEmpty(licenses)) {
                list.forEach(vo -> {
                    long did = vo.getDid().longValue();
                    List<DUserLicense> collects = licenses.stream().filter(d -> d.getUserId().longValue() == did).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collects)) {
                        vo.setLicense(collects.stream().map(l -> l.getLicenseName()).collect(Collectors.joining(",")));
                        vo.setReceiveTime(collects.get(0).getReceiveTime());
                    }
                });
            }
        }

        paramsMap = new HashMap<>();
        paramsMap.put("list", list);
        paramsMap.put("page", page);

        return paramsMap;
    }

    @Override
    public Result<Integer> modifySubsuppliers(UserUpdateVo updateVo, String password) throws Exception {
        LOGGER.info("modifySubsuppliers params updateVo: {}", updateVo);
        Result<Integer> result = new Result<>(true, null, "数据操作成功");
        // 校验必输项
        this.validate(updateVo, password);
        SUser user = new SUser();
        try {
            PropertyUtils.copyProperties(user, updateVo);
        } catch (Exception e) {
            LOGGER.error("modifySubsuppliers copyProperties error: {}", e);
            throw new BusinessException("对象转换异常");
        }
        user.setEnable(EnabledEnum.T.getValue());
        user.setUserType(UserTypeEnum.CONSUMER.getValue());
        user.setRealName(updateVo.getRealname());
        if (null == user.getId() || user.getId() == 0) {
            // 添加
            user.setPwd(passwordEncoder.encodePassword(password, jwtAuthenticationFilter.getSecureKey()));
            result.setData(this.getSUserMapper().insertSelective(user));
        } else {
            // 修改
            result.setData(this.getSUserMapper().updateByPrimaryKeySelective(user));
        }
        return result;
    }

    /**
     * 分供方数据校验
     *
     * @return
     * @throws BusinessException
     */
    private void validate(UserUpdateVo updateVo, String password) throws Exception {
        if (StringUtils.isBlank(updateVo.getName())) {
            LOGGER.info("name is not null");
            throw new BusinessException("公司名称不能为空");
        }
        if (StringUtils.isBlank(updateVo.getRealname())) {
            LOGGER.info("realname is not null");
            throw new BusinessException("用户名不能为空");
        }
        if (StringUtils.isBlank(updateVo.getPhone())) {
            LOGGER.info("phone is not null");
            throw new BusinessException("手机号不能为空");
        }
        List<SUser> sUsers = new ArrayList<>();
        if (null != updateVo.getId() && updateVo.getId() != 0) { // 修改
            SUserExample example = new SUserExample();
            example.createCriteria().andPhoneEqualTo(updateVo.getPhone()).andIdNotEqualTo(updateVo.getId()).andUserTypeEqualTo(UserTypeEnum.CONSUMER.getValue());
            sUsers = this.getSUserMapper().selectByExample(example);
        } else {
            if (StringUtils.isBlank(password)) {
                LOGGER.info("password is not null");
                throw new BusinessException("密码不能为空");
            }
            SUserExample example = new SUserExample();
            example.createCriteria().andPhoneEqualTo(updateVo.getPhone()).andUserTypeEqualTo(UserTypeEnum.CONSUMER.getValue());
            sUsers = this.getSUserMapper().selectByExample(example);
        }
        if (CollectionUtils.isNotEmpty(sUsers)) {
            LOGGER.info("current subsupplier user is exit");
            throw new BusinessException("当前分供方手机号已存在");
        }
    }

    @Override
    public Result<Map<String, Object>> subsupplierList(PageVo pageVo, UserShowVo showVo) throws Exception {
        LOGGER.info("subsupplierList params showVo: {}", showVo);
        Result<Map<String, Object>> result = new Result<>(true, null, "数据加载成功");
        Map<String, Object> map = new HashMap<>();
        SUserExample example = new SUserExample();
        SUserExample.Criteria criteria = example.createCriteria();
        example.setLimitStart(pageVo.getStartIndex());
        example.setLimitEnd(pageVo.getPageSize());
        if (StringUtils.isNotBlank(pageVo.getOrder())) {
            example.setOrderByClause(pageVo.getOrder());
        } else {
            example.setOrderByClause("id DESC");
        }
        criteria.andUserTypeEqualTo(UserTypeEnum.CONSUMER.getValue());
        criteria.andPhoneNotEqualTo("11111111111");
        if (StringUtils.isNotBlank(showVo.getPhone())) {
            criteria.andPhoneEqualTo(showVo.getPhone());
        }
        if (StringUtils.isNotBlank(showVo.getName())) {
            criteria.andNameEqualTo(showVo.getName());
        }
        pageVo.setTotalRecord(this.getSUserMapper().countByExample(example));
        map.put("users", this.getSUserMapper().selectByExample(example));
        map.put("page", pageVo);
        result.setData(map);
        return result;
    }

    @Override
    public Result<List<SUser>> subList() throws Exception {
        Result<List<SUser>> result = new Result<List<SUser>>(true, null, "数据加载成功");
        SUserExample example = new SUserExample();
        example.createCriteria().andUserTypeEqualTo(UserTypeEnum.CONSUMER.getValue()).andEnableEqualTo(EnabledEnum.T.getValue()).andPhoneNotEqualTo("11111111111");
        result.setData(this.getSUserMapper().selectByExample(example));
        return result;
    }

    @Override
    public List<SUser> getUsersByType(int userType) {
        LOGGER.info("getUsersByType param : {}", userType);

        SUserExample example = new SUserExample();
        example.createCriteria().andUserTypeEqualTo(userType);

        List<SUser> sUsers = sUserMapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(sUsers)) {
            return sUsers;
        }
        return null;
    }

    @Override
    public List<Long> getUserIdsByType(int userType) {
        LOGGER.info("getUserIdsByType param : {}", userType);

        List<SUser> sUsers = this.getUsersByType(userType);
        if (CollectionUtils.isNotEmpty(sUsers)) {
            return sUsers.stream().mapToLong(u -> u.getId()).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
        }

        return null;
    }

    @Override
    public UserShowVo getCurrentUserForDriver(Boolean truckType) throws Exception {
        Long id = this.getCurrentUserVo().getId();
        SUser user = this.getSUserMapper().selectByPrimaryKey(id);
        if (user == null) {
            throw new BusinessException("用户不存在！");
        }
        String picKey = user.getPic();

        // if(StringUtils.isNotBlank(picKey)){
        // user.setPic(QiniuUtils.generateDownloadTicket(picKey, "2", "200",
        // "200"));
        // }
        UserShowVo userShowVo = new UserShowVo();
        userShowVo.setPicKey(picKey);
        buildDriverUserVo(user, userShowVo, truckType == null ? false : truckType);
        return userShowVo;
    }

    @Override
    public boolean alreadyExists(String phone, int userType) {
        LOGGER.info("alreadySent params : {}, {}", phone, userType);
        Jedis jedis = this.getConnectionFactory().fetchJedisConnector();
        try {
            // String flag = jedis.setex(phone,seconds, code);
            String key = phone.concat(String.valueOf(userType));
            return StringUtils.isNotBlank(jedis.get(key)) == true ? true : false;
        } finally {
            jedis.close();
        }
    }

    /**
     * 构建司机显示VO
     *
     * @param user
     * @return
     */
    private void buildDriverUserVo(SUser user, UserShowVo vo, Boolean truckType) throws Exception {
        buildUserVo(user, vo, truckType);
    }

    private void buildUserVo(SUser user, UserShowVo vo, Boolean truckType) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (user.getBirthday() != null) {
            vo.setBirthday(sdf.format(user.getBirthday()));
        }

        Long userId = user.getId();
        Integer userType = user.getUserType();
        LOGGER.info("select current user userId : {}, userType : {}.", userId, userType);
        vo.setCreateTime(user.getCreateTime());
        vo.setEmail(user.getEmail());
        vo.setEnable(user.getEnable());
        vo.setGender(user.getGender());
        vo.setId(userId);
        vo.setName(user.getName());
        vo.setOpenId(user.getOpenId());
        vo.setPhone(user.getPhone());
        vo.setUserStatus(user.getUserStatus());
        if (StringUtils.isNotBlank(user.getPic())) {
            vo.setPic(QiniuUtils.generateDownloadTicket("", user.getPic(), "2", "200", "200"));
        }
        vo.setRealName(user.getRealName());
        vo.setUpdateTime(user.getUpdateTime());
        vo.setUserType(userType);
        vo.setCompanycode(user.getCompanyCode());
        vo.setInvitedcode(user.getInvitedCode() + "");
        if (UserTypeEnum.DRIVER.getValue() == userType) {
            CTruckInfoExample example = new CTruckInfoExample();
            example.createCriteria().andUserIdEqualTo(userId).andTruckTypeEqualTo(truckType == null ? false : truckType);
            List<CTruckInfo> truckInfos = this.getCTruckInfoMapper().selectByExample(example);
            if (CollectionUtils.isNotEmpty(truckInfos) && truckInfos.size() > 0) {
                vo.setDriverStatus(TruckAuditStatusEnum.getByValue(truckInfos.get(0).getStatus()).getValue());
            } else {
                vo.setDriverStatus(0);
            }
        }

        BCompanyUserExample userExample = new BCompanyUserExample();
        userExample.createCriteria().andUserIdEqualTo(userId);
        List<BCompanyUser> bCompanyUsers = this.getBCompanyUserMapper().selectByExample(userExample);
        if (CollectionUtils.isNotEmpty(bCompanyUsers)) {
            BCompanyUser bCompanyUser = bCompanyUsers.get(0);
            Long companyId = bCompanyUser.getCompanyId();
            BCompany company = this.getBCompanyMapper().selectByPrimaryKey(companyId);
            if (StringUtils.isEmpty(company.getCompanyName())) {
                vo.setCompanyName("");
            } else {
                vo.setCompanyName(company.getCompanyName());
            }
        }

        LOGGER.info("select current user userId : {}, userType : {} add userlevel and userscores.", userId, userType);
        // 承运端 没有积分
        if (userType == UserTypeEnum.SCOMPANY.getValue()) {
            BScores userScores = this.getBScoresService().getUserScores(userId, userType);
            if (userScores != null) {
                vo.setScores(userScores.getScores());
                vo.setLevelName(userScores.getLevelName());
            } else {
                BScoresLevel level = this.getBScoresLevelService().selectByLevel(userType, UserLevelEnum.LEVEL_A.getValue());
                vo.setLevelName(level.getLevelName());
                vo.setScores(BigDecimal.ZERO);
            }
        }
    }

    @Override
    public List<DUserVo> selectByCondition(String phone) {
        LOGGER.info("UserServiceImpl.selectByCondition params phone: {}", phone);
        return this.dUserViewMapper.selectByCondition(phone);
    }

    @Override
    public int updatePicById(Long id, String pic) {
        LOGGER.info("UserServiceImpl.updatePicById params id: {}, pic: {}", id, pic);
        if (null == id) {
            LOGGER.info("id is mast be not null");
            throw new BusinessException("ID不能为空");
        } else if (StringUtils.isBlank(pic)) {
            LOGGER.info("pic is mast be not null");
            throw new BusinessException("图片KEY不能为空");
        }

        DUserExtExample extExample = new DUserExtExample();
        extExample.createCriteria().andUserIdEqualTo(id);
        List<DUserExt> dUserExts = this.getDUserExtMapper().selectByExample(extExample);
        if (CollectionUtils.isNotEmpty(dUserExts)) {
            DUserExt ext = dUserExts.get(0);
            ext.setImage(pic);
            try {
                this.getDUserExtMapper().updateByPrimaryKeySelective(ext);
            } catch (Exception e) {
                LOGGER.error("UserServiceImpl.updatePicById error: {}", e);
                throw new BusinessException("图片上传异常");
            }
        }
        return 0;
    }
}
